# !/usr/bin/env python
# -*- coding:utf-8 -*-
# @FileName  :user.py
# @Time      :2022/6/28 14:15
# @Author    :吕华龙
from flask import Blueprint, jsonify, g, request, current_app
from flask_restful import Resource, reqparse, Api
from utils.send_sms import SendSMS
import random
from models.model import *
from utils.jwt_tool import JwtTool
# from utils.send_sms import send_message
import redis
from utils.redis_tool import RedisTool

user_bp = Blueprint("user_bp", __name__, url_prefix="/user")


# 此钩子函数，负责解析token
@user_bp.before_request
def login_gz():
    req = reqparse.RequestParser()
    req.add_argument("token", default="", location="headers")
    args = req.parse_args()

    j = JwtTool()
    payload = j.ver_token(args['token'])

    # 正常来说，已经解析出token了
    # 在增加一个检测当前token  是否被封禁了
    rds_tool = RedisTool()
    key = "disable_token" + args['token']
    count = rds_tool.rds.exists(key)
    if count:
        payload = None

    g.user = payload


# from functools import wraps


# 负责强制登录
def require_login(func):
    # @wraps(func)
    def warpper(*args, **kwargs):
        if not g.user:
            # return jsonify({'code': 403, 'msg': '此用户未登录'})
            return jsonify({'code': 666, 'msg': '此用户未登录'})
        return func(*args, **kwargs)

    return warpper


api = Api(user_bp)


# from utils.send_sms import send_message


# 发送短信的类视图
class SmsCode(Resource):
    def post(self):
        req = reqparse.RequestParser()
        req.add_argument("mobile", required=True, help="手机号必须输入")
        args = req.parse_args()

        print("手机号mobile:", args['mobile'])

        # 生成验证码
        code = random.randint(100000, 999999)
        sms = SendSMS()
        # send_rs = send_message(args['mobile'], (str(code), 5))
        # print("手机号，验证码：", send_rs, code)
        send_rs = sms.send_sms(args['mobile'], (str(code), 5))
        print(send_rs)
        if send_rs:
            # 存入redis
            # rds = redis.Redis(host='localhost', db=2, port=6379, password=123)
            # rds.set(send_rs, code, ex=60)
            return jsonify({'code': 200, 'msg': '发送成功'})
        else:
            return jsonify({'code': 400, 'msg': '发送失败'})


# 校验验证码视图
class UserView(Resource):
    def post(self):
        # 获取参数
        req = reqparse.RequestParser()
        req.add_argument("mobile", required=True)
        req.add_argument("code", required=True)
        args = req.parse_args()
        print("验证码", args['code'])
        # 需要验证一下手机号
        sms = SendSMS()
        # sms = send_message(args['mobile'], str(args['code']))
        # ver_rs = sms.ver_code(args['mobile'], args['code'])
        # if not ver_rs:
        #     return jsonify({'code': 400, 'msg': '验证码错误'})
        # 去数据库查询、判断手机号是否存在
        user_info = User.query.filter(User.mobile == args['mobile']).first()
        # 不存在，说明是第一次登录，就需要注册
        if not user_info:
            # 注册就是往用户表中添加一条数据
            user = User(mobile=args['mobile'], user_name=args['mobile'])
            db.session.add(user)
            db.session.commit()
        # 走到这一步，就说明用户一定存在了，直接登陆就可以了
        user_info = User.query.filter(User.mobile == args['mobile']).first()

        # 生成token
        # 实例化jwt工具类
        token_obj = JwtTool()
        token = token_obj.create_token({
            "user_id": user_info.uid,
            "mobile": args['mobile']
        }, 2 * 3600)  # 有效期2小时

        long_token = token_obj.create_token({
            "user_id": user_info.uid,
            "mobile": args['mobile']
        }, 20 * 24 * 3600)  # 有效期一个月
        return jsonify({'code': 200, 'msg': '登陆成功', "user": {
            "uid": user_info.uid,
            "mobile": args['mobile'],
        }, "token": token, "long_token": long_token})

    # 获取用户个人信息
    @require_login
    def get(self):
        print("g对象的内容是>>>>>>>:", g.user)
        user_id = g.user["user_id"]  # 拿到当前登录的用户ID
        user_info = User.query.filter(User.uid == user_id).first()  # 当前用户的使用信息

        if not user_info:
            return jsonify({'code': 400, 'msg': '用户不存在'})

        head_img = "aoteman.png"
        if user_info.img:
            head_img = user_info.img

        head_img = current_app.config["QINIU_HOST"] + head_img
        return jsonify({'code': 200, 'msg': '用户信息获取成功',
                        "user": {"mobile": user_info.mobile, "follow_count": user_info.following_count,
                                 "fans_count": user_info.fans_count, "head_img": head_img}})


class Token(Resource):
    def get(self):
        req = reqparse.RequestParser()
        req.add_argument("token2", default="", location="headers")
        args = req.parse_args()

        j = JwtTool()
        payload = j.ver_token(args["token2"])
        if not payload:
            return jsonify({
                "code": 400,
                "msg": "token失效"
            })

        # 生成一个新的token,返回回去
        new_token = j.create_token(payload, exp=2 * 3600)

        return jsonify({
            "code": 200,
            "msg": "获取新token成功",
            "token": new_token
        })

    # 封禁当前用户的token
    @require_login
    def delete(self):
        # 1.获取到token
        req = reqparse.RequestParser()
        req.add_argument("token", location="headers")
        args = req.parse_args()

        # 把token封禁掉
        rds_tool = RedisTool()
        # key = "disable_token" + args['token']
        key = "disable_token"
        # rds_tool.rds.set(key, "1", ex=2 * 3600)
        rds_tool.rds.set(key, args['token'])

        # 返回
        return jsonify({'code': 200, 'msg': '退出登录'})


from utils.qiniu_upload import QiniuTool


# 上传头像
class HeadImg(Resource):
    @require_login
    def post(self):
        img = request.files.get("img")
        img.save("./static/" + img.filename)
        # 从本地上传到七牛云
        qn = QiniuTool()
        file_path = qn.upload_file("./static/" + img.filename, img.filename)
        # 存到当前用户的数据库
        try:
            User.query.filter(User.uid == g.user["user_id"]).update(img=file_path)
            db.session.commit()
            return jsonify({'code': 200, 'msg': '头像上传成功'})
        except Exception as e:
            print("修改头像报错", e)
            return jsonify({'code': 400, 'msg': '头像上传失败'})


api.add_resource(SmsCode, "/sms")
api.add_resource(UserView, "/user")
api.add_resource(Token, "/new_token")
api.add_resource(HeadImg, "/head_img")
